﻿namespace Json2Model
{
    public class JObjectFormater
    {
        public string Format(string jsonStr)
        {
            var obj = JsonConvert.DeserializeObject(jsonStr);
            return JsonConvert.SerializeObject(obj,Formatting.Indented);
        }
        public IList<JModel> Format(string jsonStr, string name = "Root")
        {
            JObject? jObj = JsonConvert.DeserializeObject(jsonStr) as JObject;
            return Format(jObj, name);
        }
        public IList<JModel> Format(JObject? jObj,string name ="Root")
        {
            if(jObj==null)
                return new List<JModel>();
            AnalysisJObject(jObj, name);
            return models;
        }

        public List<JModel> models = new List<JModel>();
        public JModel AnalysisJObject(JObject jObj,string name)
        {
            JModel model = new JModel{Name=name.Trim()};
            foreach (JProperty j in jObj.Children())
            {
                model.Attributes.Add(AnalysisJProperty(j)!);
            }
            if (!models.Contains(model))
                models.Add(model);
            return model;
        }

        public JAttribute? AnalysisJProperty(JProperty jProperty)
        {
            if (jProperty == null || jProperty.Children().Count() == 0)
            {
                return null;
            }
            var jToken = jProperty.Children().First();
            if (jToken is JValue)
            {
                return new JAttribute { Name = jProperty.Name.Trim(), TypeName = Converter.ToTypeName(Converter.ToType(jToken.Type))};
            }
            if (jToken is JObject)
            {
                AnalysisJObject((JObject)jToken, jProperty.Name.Trim());
                return new JAttribute { Name = jProperty.Name.Trim(), TypeName = Converter.TypeNameFormat(jProperty.Name.Trim()) };
            }
            if (jToken is JArray)
            {
                return new JAttribute { Name = jProperty.Name.Trim(), TypeName = AnalysisJArray((JArray)jToken, jProperty) };
            }
            return null;
        }
        public string AnalysisJArray(JArray jArray, JProperty jProperty)
        {
            var jToken = jArray.Children().First();
            if (jToken is JValue)
                return $"{ArrayType}<{Converter.ToTypeName(Converter.ToType(jToken.Type))}>";
            if (jToken is JObject)
            {
                AnalysisJObject((JObject)jToken,Converter.ArrayItemNameFormat(jProperty.Name.Trim()));
                return $"{ArrayType}<{Converter.ArrayItemNameFormat(jProperty.Name.Trim())}>";
            }
            if (jToken is JArray)
                return $"{ArrayType}<{AnalysisJArray((JArray)jToken, jProperty)}>";
            return string.Empty;
        }
        public static string ArrayType { get; set; } = "IList";
    }
}
